/*
 * @(#)IHEConfigConstructor.java
 * Date 2013-10-14
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.ihecommon.inject;

import org.yaml.snakeyaml.constructor.Constructor;

import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.Tag;

import us.hornerscorners.lamppost.config.BasicServiceConfig;
import us.hornerscorners.lamppost.ihecommon.config.IHEServiceType;
import us.hornerscorners.lamppost.ihecommon.config.ElasticSearchConfig;
import us.hornerscorners.lamppost.ihecommon.config.RegistryServiceConfig;
import us.hornerscorners.lamppost.ihecommon.config.RepositoryServiceConfig;
import us.hornerscorners.lamppost.ihecommon.config.XCAGatewayConfig;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-10-14
 * @author         Jim Horner
 */
public class IHEConfigConstructor extends Constructor {

    /**
     * Constructs ...
     *
     */
    @SuppressWarnings("unchecked")
    public IHEConfigConstructor() {

        super();

        this.yamlConstructors.put(new Tag("!elasticsearch"),
                                  new ConstructServiceConfig(new ElasticSearchConfig(),
                                      ElasticSearchConfig.class));

        this.yamlConstructors.put(new Tag("!registry"),
                                  new ConstructServiceConfig(new RegistryServiceConfig(),
                                      RegistryServiceConfig.class));
        this.yamlConstructors.put(
            new Tag("!repository"),
            new ConstructServiceConfig(
                new RepositoryServiceConfig(), RepositoryServiceConfig.class));
        this.yamlConstructors.put(new Tag("!xca"),
                                  new ConstructServiceConfig(new XCAGatewayConfig(),
                                      XCAGatewayConfig.class));
        this.yamlConstructors.put(new Tag("!pix"),
                                  new ConstructBasicServiceConfig(IHEServiceType.PIX));
        this.yamlConstructors.put(new Tag("!pdq"),
                                  new ConstructBasicServiceConfig(IHEServiceType.PDQ));
    }

    /**
     * Class description
     *
     *
     * @version        v1.0, 2013-10-14
     * @author         Jim Horner
     */
    private class ConstructBasicServiceConfig extends ConstructMapping {

        /** Field description */
        private final IHEServiceType configType;

        /**
         * Constructs ...
         *
         *
         * @param configType
         */
        public ConstructBasicServiceConfig(IHEServiceType configType) {

            super();
            this.configType = configType;
        }

        /**
         * Method description
         *
         *
         * @param node
         *
         * @return
         */
        @Override
        public Object construct(Node node) {

            BasicServiceConfig result = new BasicServiceConfig(this.configType);

            node.setType(BasicServiceConfig.class);
            node.setTwoStepsConstruction(true);

            return result;
        }
    }


    /**
     * Class description
     *
     *
     * @version        v1.0, 2013-10-14
     * @author         Jim Horner
     */
    private class ConstructServiceConfig<T> extends ConstructMapping {

        /** Field description */
        private final Class<T> clazz;

        /** Field description */
        private final T config;

        /**
         * Constructs ...
         *
         *
         * @param config
         * @param clazz
         */
        public ConstructServiceConfig(T config, Class<T> clazz) {

            super();
            this.config = config;
            this.clazz = clazz;
        }

        /**
         * Method description
         *
         *
         * @param node
         *
         * @return
         */
        @Override
        public Object construct(Node node) {

            node.setType(this.clazz);
            node.setTwoStepsConstruction(true);

            return this.config;
        }
    }
}
